package com.rlax.framework.plugin.reids.shiro;

import com.jfinal.plugin.redis.Redis;
import org.apache.shiro.cache.CacheException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.Set;

/**
 * RedisCache for shiroCache
 * @author Rlax
 *
 * @param <K>
 * @param <V>
 */
public class RedisShiroCache<K, V> implements org.apache.shiro.cache.Cache<K, V> {
	
	private final static Logger logger = LoggerFactory.getLogger(RedisShiroCache.class);
	
    public static final String SHIRO_KEY = "shiro_";
    private int expire = 0;

    public RedisShiroCache(int expire) {
        this.expire = expire;
    }

    public V get(K key) throws CacheException {
    	logger.debug("reids cache get key {}", key);
        if (key == null) {
            return null;
        } else {
            return Redis.use().get(SHIRO_KEY + key);
        }
    }

    public V put(K key, V value) throws CacheException {
    	logger.debug("reids cache put key {}, value {}", key, value);
        Redis.use().set(SHIRO_KEY + key, value);
        Redis.use().expire(SHIRO_KEY + key, expire);
        return value;
    }

    /**
     * shiro 的默认删除KEY：用户的
     *
     * @throws CacheException CacheException
     */
    public V remove(K key) throws CacheException {
    	logger.debug("reids cache delete key {}", key);
        V previous = get(key);
        return previous;
    }

    public void clear() throws CacheException {
    	logger.debug("reids cache clear all keys");
        try {
            Set<String> keys = Redis.use().keys(SHIRO_KEY + "*");
            Redis.use().del(keys);
        } catch (Throwable t) {
            throw new CacheException(t);
        }
    }

    public int size() {
        Set<String> keys = Redis.use().keys(SHIRO_KEY + "*");
        return keys.size();
    }

    @SuppressWarnings("unchecked")
	public Set<K> keys() {
        return (Set<K>) Redis.use().hkeys(SHIRO_KEY);
    }

    @SuppressWarnings("unchecked")
	public Collection<V> values() {
        return Redis.use().hvals(SHIRO_KEY);
    }
}
